<!-- 组件 -->
<template>
  <view>
    <van-cell-group>
      <van-field
        v-show="!props.hidden"
        v-model="_value"
        :label="props.formItem?.title"
        :placeholder="props.placeholder"
        readonly
        type="number"
        :input-align="FieldInputAlign.DEFAULT"
      />
    </van-cell-group>
  </view>
</template>

<script setup lang="ts">
  import { computed, ref, watch } from 'vue';
  import { evalFormual } from '@/utils/evalFormual';
  import { FieldInputAlign } from '@/enums/formEnum';
  import { isEmpty, isString } from '@/utils/is';

  const emits = defineEmits(['update:value', 'labelShow']);
  const props = defineProps({
    value: {
      type: [String, Number],
      default: null,
    },
    required: {
      type: Boolean,
      default: false,
    },
    readonly: {
      type: Boolean,
      default: false,
    },
    //隐藏组件的公共属性
    formula: {
      type: Object,
      default: () => {
        return {
          showFormula: '', //回显用，因为包含表单字段的时候会出现表单名称
          calcFormula: '', //解析用，表单名称对应为formData.fieldxxxx
        };
      },
    },
    formItem: {
      type: Object,
      default: () => {},
    },
    formData: {
      type: Object,
      default: () => {
        return {};
      },
    },
    placeholder: {
      type: String,
      default: '计算结果',
    },
    explain: {
      type: Array,
      default: () => {
        return [];
      },
    },
    jsCode: {
      type: String,
      default: '',
    },
    enableScan: {
      type: Boolean,
      default: false,
    },
    isPlus: {
      type: Boolean,
      default: false,
    },
    precision: {
      type: Number,
      default: 0,
    },
    index: {
      type: Number,
      default: 0,
    },
    hidden: {
      type: Boolean,
      default: false,
    },
  });
  /** 计算属性：_value */
  const _value = computed({
    get() {
      return isEmpty(props.value) ? '' : parseNumber(props.value);
    },
    set(val) {
      emits('update:value', parseNumber(val));
    },
  });
  const parseNumber = (val: string | number) => {
    if (isString(val)) {
      return props.precision > 0
        ? parseFloat(parseFloat(val).toFixed(props.precision))
        : parseInt(val);
    } else {
      return val;
    }
  };

  const execute = ref();
  const explainStr = computed(() => {
    //execute.value = '';
    let explain = '';
    props.explain.forEach((item) => {
      const v = String(item.symbol || item);
      if (/[0-9.]$/.test(v)) {
        explain += v;
      } else {
        explain += v + ' ';
      }
    });
    return explain;
  });
  const doExc = () => {
    try {
      if (!(execute.value instanceof Function)) {
        if (props.isPlus) {
          const jsExplain = props.jsCode.replace(/\[\?\]/g, (m) => '[$_index]');
          execute.value = new Function(
            'formData',
            `let $_index = ${
              props.index > 0 ? props.index - 1 : 0
            }; ${jsExplain} return execute(formData)`,
          );
        } else {
          execute.value = new Function('formData', `return ${explainStr.value}`);
        }
      }
      let result = execute.value(props.formData);
      _value.value =
        props.precision > 0
          ? Number.isNaN(result)
            ? '' //NaN
            : parseFloat(result.toFixed(props.precision))
          : parseInt(result);
    } catch (e) {
      _value.value = ''; //NaN
      console.log(e);
    }
  };
  const doFormula = () => {
    let hidden = evalFormual(props.formula.calcFormula, props.formData);
    //如果隐藏，同时也隐藏label,通知父组件去隐藏，因为label不在当前界面
    //调用父组件FormDesignRender 的方法：
    emits('labelShow', props.formItem, hidden);
  };

  watch(
    () => props.formData,
    () => {
      doExc();
      doFormula();
    },
    { immediate: true, deep: true },
  );
</script>

<style scoped></style>
